package com.ubxtech.gateway.util;

import cn.hutool.core.util.StrUtil;
import com.ubxtech.core.context.ContextConstants;
import com.ubxtech.core.enums.UserAgentSystemEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

/**
 * 
 * 功能说明：IP地址
 * 
 * IPUtils.java
 * 
 * Original Author: steven.liang,2017年9月9日上午9:43:37
 * 
 * Copyright (C)2012-2017 深圳优必选科技 All rights reserved.
 */
public class IPUtils {
	private static Logger logger = LoggerFactory.getLogger(IPUtils.class);

	/**
	 * 获取IP地址
	 * 
	 * 使用Nginx等反向代理软件， 则不能通过request.getRemoteAddr()获取IP地址
	 * 如果使用了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP地址，X-Forwarded-For中第一个非unknown的有效IP字符串，则为真实IP地址
	 */
	public static String getIpAddr(ServerHttpRequest request) {
    	String ip = null;
        try {
            ip = request.getHeaders().getFirst("x-forwarded-for");
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeaders().getFirst("Proxy-Client-IP");
            }
            if (StrUtil.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeaders().getFirst("WL-Proxy-Client-IP");
            }
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeaders().getFirst("HTTP_CLIENT_IP");
            }
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeaders().getFirst("HTTP_X_FORWARDED_FOR");
            }
            if (StrUtil.isEmpty(ip) || "unKnown".equalsIgnoreCase(ip)) {
                ip = request.getHeaders().getFirst("X-Real-IP");
            }
            if (StrUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                InetSocketAddress inetSocketAddress = request.getRemoteAddress();
                if (inetSocketAddress!=null) {
                    ip = inetSocketAddress.getHostString();
                }

            }
        } catch (Exception e) {
        	logger.error("IPUtils ERROR ", e);
        }

        if (!StrUtil.isEmpty(ip) && ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

    /**
     * 得到本地服务器ip地址
     * @author Victor.Xiao
     * @date 2020-01-17 10:10
     * @return java.util.Set<java.lang.String>
    */
    public static Set<String> getLocalIpAddrSet() {
        Set<String> ipList = new HashSet<>();
        try
        {
            for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                NetworkInterface netInterface = en.nextElement();
                String name = netInterface.getName();
                if (!name.contains("docker") && !name.contains("lo")) {
                    for (Enumeration<InetAddress> enumIpAddr = netInterface.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                        //获得IP
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()) {
                            String ipAddress = inetAddress.getHostAddress();
                            if (!ipAddress.contains("::") && !ipAddress.contains("0:0:") && !ipAddress.contains("fe80")) {
                                System.out.println(ipAddress);
                                if(!"127.0.0.1".equals(ipAddress)){
                                    ipList.add(ipAddress);
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            logger.error("Failed to get local ip list. " + e.getMessage());
            throw new RuntimeException("Failed to get local ip list");
        }
        return ipList;
    }

    /**
     * 得到本地服务器ip地址
     *
     * @return java.util.Set<java.lang.String>
     * @author Victor.Xiao
     * @date 2020-01-17 10:10
     */
    public static String getLocalIpAddr() {
        Set<String> set = getLocalIpAddrSet();
        if(set.size()==0){
            return "127.0.0.1";
        }
        return set.iterator().next();

    }


    /**
     * 判断哪种类型的客户端,方便支持多客户端登录
     * @author Victor.Xiao
     * @since 2023-12-25 15:51
     * @param request request
     * @return com.ubxtech.core.enums.UserAgentSystemEnum
     */
    public static UserAgentSystemEnum getUserAgentType(ServerHttpRequest request) {
        String value = request.getHeaders().getFirst(ContextConstants.HEADER_USER_AGENT);

        if (StrUtil.isEmpty(value)) {
            return UserAgentSystemEnum.PC;
        }
        if (value.contains(UserAgentSystemEnum.ANDROID.toString().toLowerCase())) {
            return UserAgentSystemEnum.ANDROID;
        }else if (value.contains(UserAgentSystemEnum.IPHONE.toString().toLowerCase())) {
            return UserAgentSystemEnum.IPHONE;
        }
        return UserAgentSystemEnum.PC;
    }
}
